<script lang="ts" setup>
import { ref, reactive, onMounted, computed } from 'vue';
import useStore from '@/stores';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { UserPrivil } from '@/model/base-enum';
import { getErrorTranslate, traduction } from '@/utils/language';
import { getKvmData, setKvmService } from './services/kvm.services';
import { IKVMData } from '@/model/Service/KVM-interface';
import { BaseValidators } from '@/validators/base-validators';
import {
  uskeyboardTable,
  JS_KEY_A,
  JS_KEY_Z,
  JS_KEY_0,
  JS_KEY_9,
  JS_KEY_SEMI,
  JS_KEY_QUOTO,
  JS_KEY_BR1,
  JS_KEY_QUOT,
  JS_KEY_FF_SEMI,
  JS_KEY_FF_PLUS,
  JS_KEY_FF_MIN,
  JS_KEY_0P,
  JS_KEY_DIVP,
  JS_KEY_OR_1,
} from './utils/keysCode';
import { showFailedMessage, showSuccessMessage } from '@/utils/composition';
import { useRouter } from 'vue-router';
import { loading } from '@/utils/composition';
import ErrorIcon from '@/components/ErrorIcon/ErrorIcon.vue';
import ClearableIcon from '@/components/ClearableIcon/ClearableIcon.vue';
import { getMessageId, compareObjectEqual, deepClone } from '@/utils/utils';

const store = useStore();
const router = useRouter();
// 系统锁定状态
const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});
const isConfigureUser = checkPrivil(UserPrivil.userConfig);
const isOemSecurityMgmtUser = checkPrivil(UserPrivil.securityConfig);
const isOemKvmUser = checkPrivil(UserPrivil.remoteControl);
// 常规配置权限
const isBaseConfig = checkPrivil(UserPrivil.baseConfig);

const kvmData: IKVMData = reactive({
  activatedSessionsType: null,
  enabled: false,
  hotEnabled: false,
  encryptionConfigurable: false,
  encryptionEnabled: false,
  localKvmEnabled: false,
  autoCloseLocalDisplay: false,
  maximumNumberOfSessions: null,
  numberOfActiveSessions: null,
  persistentUSBConnectionEnabled: false,
  port: '',
  sessionTimeoutMinutes: '',
  visibleJavaKvm: false,
  autoOSLockEnabled: false,
  autoOSLockKey: ['', '', '', ''],
  autoOSLockType: null,
});
const formRef = ref();
let queryParams: object = {};
// 保存初始值
let oldKvmData: any;
const customShow = ref(false);
// 保存按钮禁用
let saveBtnState = ref(false);
const encryptionShow = ref(false);

const popoverVisible = reactive({
  port: false,
  sessionTimeoutMinutes: false,
});
const autoLockMsg = ref('');
function init(data: any) {
  let sessionTimeoutMinutes = data.SessionTimeoutMinutes;
  if (sessionTimeoutMinutes || sessionTimeoutMinutes === 0) {
    sessionTimeoutMinutes = sessionTimeoutMinutes.toString();
  }

  let port = data.Port;
  if (port || port === 0) {
    port = port.toString();
  }

  kvmData.activatedSessionsType = data.ActivatedSessionsType;
  kvmData.enabled = data.Enabled;
  kvmData.hotEnabled = data.DisableKeyboardDuringBiosStartup;
  kvmData.encryptionConfigurable = data.EncryptionConfigurable;
  kvmData.encryptionEnabled = data.EncryptionEnabled;
  kvmData.localKvmEnabled = data.LocalKvmEnabled;
  kvmData.autoCloseLocalDisplay = data.AutoCloseLocalDisplay;
  kvmData.maximumNumberOfSessions = data.MaximumNumberOfSessions;
  kvmData.numberOfActiveSessions = data.NumberOfActiveSessions;
  kvmData.persistentUSBConnectionEnabled = data.PersistentUSBConnectionEnabled;
  kvmData.port = port;
  kvmData.sessionTimeoutMinutes = sessionTimeoutMinutes;
  kvmData.visibleJavaKvm = data.VisibleJavaKvm;
  kvmData.autoOSLockEnabled = data.AutoOSLockEnabled;
  kvmData.autoOSLockType = data.AutoOSLockType;
  setAutoLockKey(data);
  oldKvmData = deepClone(kvmData);
  if (kvmData.autoOSLockEnabled && kvmData.autoOSLockType === 'Custom') {
    customShow.value = true;
  }
  if (kvmData.encryptionConfigurable === true) {
    encryptionShow.value = true;
  } else {
    encryptionShow.value = false;
  }
  computedState();
}

function setAutoLockKey(data: any) {
  if (data.AutoOSLockKey.length === 1) {
    kvmData.autoOSLockKey = ['', '', '', ''];
  } else {
    data.AutoOSLockKey.forEach((item: string, index: number) => {
      if (item) {
        kvmData.autoOSLockKey[index] = item;
      } else {
        kvmData.autoOSLockKey[index] = '';
      }
    });
  }
}

const autoOSLockTypeList = [
  {
    label: traduction('SERVICE_WBS_CRE_CUSTOM'),
    id: 'Custom',
  },
  {
    label: traduction('SERVICE_WBS_CRE_WINDOWS'),
    id: 'Windows',
  },
];
// kvm使能
function kvmChange() {
  computedState();
}
// 端口
function portChange(val: any) {
  oldKvmData.port = oldKvmData.port.toString();
  computedState();
}

// 恢复端口默认值
function restFN() {
  kvmData.port = '2198';
  computedState();
}
// 超时时长
function sessionTimeout() {
  computedState();
}
// 通信加密
function encryptionChange() {
  computedState();
}
// 本地KVM
function localKvm() {
  computedState();
}
// 远程连接时关闭本地kvm
function kvmAutoDisable() {
  computedState();
}
// 虚拟鼠标持续连接
function keyboardChange() {
  computedState();
}
// 开启系统自动锁定
function autoOSLockChange(val: boolean) {
  if (kvmData.autoOSLockEnabled && kvmData.autoOSLockType === 'Custom') {
    customShow.value = true;
  } else {
    customShow.value = false;
  }
  computedState();
}
// 修改自动锁定方式
function sessionAutoOSTypeChange(val: string) {
  if (val !== 'Custom') {
    customShow.value = false;
  } else {
    customShow.value = true;
  }
  computedState();
}

// 清空快捷键输入框
function clearNumberOfActiveSessions() {
  kvmData.autoOSLockKey = ['', '', '', ''];
  computedState();
}

// 校验规则
const kvmRules = {
  port: [
    BaseValidators.Required({ message: traduction('VALIDTOR_RANGE') }),
    BaseValidators.Number({ message: traduction('VALIDTOR_RANGE') }),
    BaseValidators.Integer({ message: traduction('VALIDTOR_RANGE') }),
    BaseValidators.Range({ range: [1, 65535] }),
  ],
  sessionTimeoutMinutes: [
    BaseValidators.Required({ message: traduction('SERVICE_VNC_TIMEOUT_TIP') }),
    BaseValidators.Number({ message: traduction('SERVICE_VNC_TIMEOUT_TIP') }),
    BaseValidators.Integer({ message: traduction('SERVICE_VNC_TIMEOUT_TIP') }),
    BaseValidators.Range({ range: [0, 480] }),
  ],
};

// 快捷键输入
function setDefineKey(e: any, number: number) {
  let keysym;
  const keysLocation = e.location || e.keyLocation;
  // 意大利键盘模式下，按下右边Alt键，组合键输入框内应显示为"AltGraph"
  if (
    typeof e.key !== 'undefined' &&
    e.key !== 'MozPrintableKey' &&
    e.key !== 'Alt' &&
    keysLocation !== 2
  ) {
    keysym = e.key;
  } else if (
    (e.key !== 'MozPrintableKey' && e.key === 'Alt' && keysLocation === 2) ||
    e.key === 'AltGraph'
  ) {
    keysym = 'AltGraph';
  } else {
    keysym = getKeysym(e);
  }
  if (keysym) {
    kvmData.autoOSLockKey[number] = keysym;
  }
  computedState();
}
function keyCode(keysCode: any) {
  return (
    (keysCode >= JS_KEY_A && keysCode <= JS_KEY_Z) ||
    (keysCode >= JS_KEY_0 && keysCode <= JS_KEY_9) ||
    (keysCode >= JS_KEY_SEMI && keysCode <= JS_KEY_QUOTO) ||
    (keysCode >= JS_KEY_BR1 && keysCode <= JS_KEY_QUOT) ||
    keysCode === JS_KEY_FF_SEMI ||
    keysCode === JS_KEY_FF_PLUS ||
    keysCode === JS_KEY_FF_MIN
  );
}
// 获取按键
function getKeysym(e: any): string | number {
  const keysCode = e.keyCode || e.which || e.charCode;
  for (const key of uskeyboardTable) {
    if (key[0] === keysCode) {
      if (keyCode(keysCode)) {
        return e.shiftKey ? key[4] : key[3];
      } else if ((keysCode >= JS_KEY_0P && keysCode <= JS_KEY_DIVP) || keysCode === JS_KEY_OR_1) {
        return key[3];
      } else {
        return key[2];
      }
    }
  }
  return 'Unknow';
}

// 保存按钮的状态,数据是否修改
function computedState() {
  queryParams = {};
  if (kvmData.enabled !== oldKvmData['enabled']) {
    queryParams['Enabled'] = kvmData.enabled;
  }
  if (kvmData.hotEnabled !== oldKvmData['hotEnabled']) {
    queryParams['DisableKeyboardDuringBiosStartup'] = kvmData.hotEnabled;
  }
  if (kvmData.port !== oldKvmData['port']) {
    queryParams['Port'] = Number(kvmData.port as any);
  }
  if (kvmData.sessionTimeoutMinutes !== oldKvmData['sessionTimeoutMinutes']) {
    queryParams['SessionTimeoutMinutes'] = Number(kvmData.sessionTimeoutMinutes as any);
  }
  if (encryptionShow.value && kvmData.encryptionEnabled !== oldKvmData['encryptionEnabled']) {
    queryParams['EncryptionEnabled'] = kvmData.encryptionEnabled;
  }
  if (kvmData.localKvmEnabled !== oldKvmData['localKvmEnabled']) {
    queryParams['LocalKvmEnabled'] = kvmData.localKvmEnabled;
  }
  if (kvmData.autoCloseLocalDisplay !== oldKvmData['autoCloseLocalDisplay']) {
    queryParams['AutoCloseLocalDisplay'] = kvmData.autoCloseLocalDisplay;
  }
  if (kvmData.persistentUSBConnectionEnabled !== oldKvmData['persistentUSBConnectionEnabled']) {
    queryParams['PersistentUSBConnectionEnabled'] = kvmData.persistentUSBConnectionEnabled;
  }
  if (kvmData.autoOSLockEnabled !== oldKvmData['autoOSLockEnabled']) {
    queryParams['AutoOSLockEnabled'] = kvmData.autoOSLockEnabled;
  }
  if (kvmData.autoOSLockEnabled === true) {
    if (kvmData.autoOSLockType !== oldKvmData['autoOSLockType']) {
      queryParams['AutoOSLockType'] = kvmData.autoOSLockType;
    }
    const keyArray = JSON.parse(JSON.stringify(kvmData.autoOSLockKey));
    if (
      kvmData.autoOSLockType === 'Custom' &&
      keyArray.toString() !== oldKvmData['autoOSLockKey'].toString()
    ) {
      queryParams['AutoOSLockKey'] = keyArray;
    }
  }
  const isAutoLockErr = autoLockValid();
  autoLockMsg.value = isAutoLockErr ? traduction('SERVICE_SHORTCUT_IS_NULL') : '';
  // 表单是否修改
  const isChange = JSON.stringify(queryParams) !== '{}';
  let hasError = true;
  formRef.value
    .validate((result: boolean) => {
      hasError = result;
    })
    .then(() => {
      saveBtnState.value = hasError && isChange && !isAutoLockErr;
    });
}
// 自定义快捷键校验
function autoLockValid() {
  let hasAutoLockKey = false;
  for (let i = 0; i < kvmData.autoOSLockKey.length; i++) {
    if (kvmData.autoOSLockKey[i] !== '') {
      hasAutoLockKey = true;
    }
  }
  if (hasAutoLockKey || !customShow.value || !kvmData.autoOSLockEnabled) {
    return false;
  } else {
    return true;
  }
}
// 保存
function submitBtn() {
  loading(true);
  saveBtnState.value = false;
  setKvmService(queryParams)
    .then(res => {
      if (res.data.error) {
        const errorId = res.data.error;
        const errorMsg = getErrorTranslate(errorId[0].code as string);
        showFailedMessage(errorMsg);
        init(res.data.data);
      } else {
        init(res.data);
        showSuccessMessage();
      }
      loading(false);
    })
    .catch(error => {
      loading(false);
      const errorId = getMessageId(error.data);
      const errorMsg = getErrorTranslate(errorId[0].code as string);
      showFailedMessage(errorMsg);
      init(error.data.data);
    });
}

// 查看KVM会话
function jumpToOnline() {
  if (kvmData.numberOfActiveSessions !== null && kvmData.numberOfActiveSessions > 0) {
    router.push('/navigate/user/online-users');
  }
}

onMounted(() => {
  loading(true);
  getKvmData()
    .then(res => {
      init(res.data);
      loading(false);
    })
    .catch(error => {
      loading(false);
    });
});
</script>

<template>
  <div id="kvmView" class="kvm-container">
    <el-form
      id="kvmForm"
      ref="formRef"
      :model="kvmData"
      label-width="auto"
      label-position="left"
      :rules="kvmRules"
      :hide-required-asterisk="false"
      :validate-on-rule-change="false"
      :disabled="isSystemLock || !(isOemSecurityMgmtUser || isOemKvmUser || isBaseConfig)"
    >
      <!-- kvm使能 -->
      <el-form-item :label="$t('SERVICE_KVM_ABLE_LABEL')" class="switch-value-item" size="default">
        <el-switch
          id="kvmEnable"
          v-model="kvmData.enabled"
          :disabled="!isOemSecurityMgmtUser"
          @change="kvmChange"
        />
      </el-form-item>
      <!-- kvm热键使能 -->
      <el-form-item :label="$t('SERVICE_KVM_DISABLE_LABEL')" class="switch-value-item" size="default">
        <el-switch
          id="kvmHotEnable"
          v-model="kvmData.hotEnabled"
          :disabled="!isOemKvmUser"
          @change="kvmChange"
        />
      </el-form-item>
      <!-- 端口 -->
      <el-form-item :label="$t('SERVICE_PORT')" prop="port" size="default">
        <el-tooltip
          v-model:visible="popoverVisible.port"
          class="box-item"
          placement="top"
          popper-class="kvmPortInputTip"
          trigger="focus"
          trigger-keys
        >
          <template #content>
            <span id="kvmPortInputTip">{{ $t('VALIDTOR_RANGE') }}</span>
          </template>
          <el-input
            v-model="kvmData.port"
            v-addId.input="'kvmPort'"
            v-clearable
            type="text"
            clearable
            :disabled="!isOemSecurityMgmtUser"
            @input="portChange"
            @focus="popoverVisible.port = true"
            @blur="popoverVisible.port = false"
          >
            <template #suffix>
              <ErrorIcon />
              <ClearableIcon />
            </template>
          </el-input>
        </el-tooltip>
        <el-button
          v-if="isOemSecurityMgmtUser && !isSystemLock"
          id="resetPort"
          type="text"
          @click="restFN"
        >
          {{ $t('SERVICE_DEFAULT_VALUE') }}
        </el-button>
      </el-form-item>
      <!-- 超时时长 -->
      <el-form-item
        :label="$t('SERVICE_TIME_OUT_MINUTES')"
        prop="sessionTimeoutMinutes"
        size="default"
      >
        <el-tooltip
          v-model:visible="popoverVisible.sessionTimeoutMinutes"
          class="box-item"
          placement="top"
          trigger="focus"
          trigger-keys
        >
          <template #content>
            <span id="kvmTimeoutInputTip">{{ $t('SERVICE_VNC_TIMEOUT_TIP') }}</span>
          </template>
          <el-input
            v-model="kvmData.sessionTimeoutMinutes"
            v-addId.input="'timeoutKvm'"
            v-clearable
            clearable
            type="text"
            :disabled="!isBaseConfig"
            @input="sessionTimeout"
            @focus="popoverVisible.sessionTimeoutMinutes = true"
            @blur="popoverVisible.sessionTimeoutMinutes = false"
          >
            <template #suffix>
              <ErrorIcon />
              <ClearableIcon />
            </template>
          </el-input>
        </el-tooltip>
      </el-form-item>
      <!-- 通信加密 -->
      <el-form-item
        v-if="encryptionShow"
        prop="encryption"
        :label="$t('SERVICE_ENCRYPTION')"
        class="switch-value-item"
        size="default"
      >
        <el-switch
          id="kvmEncryption"
          v-model="kvmData.encryptionEnabled"
          :disabled="!isOemKvmUser"
          @change="encryptionChange"
        />
      </el-form-item>
      <!-- 本地kvm -->
      <el-form-item
        prop="localKvm"
        :label="$t('SERVICE_LOCAL_KVM')"
        class="switch-value-item"
        size="default"
      >
        <el-switch
          id="kvmLocal"
          v-model="kvmData.localKvmEnabled"
          :disabled="!isOemKvmUser"
          @change="localKvm"
        />
      </el-form-item>
      <!-- 远程kvm连接时自动关闭本地kvm -->
      <el-form-item
        prop="autoCloseLocalDisplay"
        :label="$t('SERVICE_AUTO_DISABLE_KVM')"
        class="switch-value-item"
        size="default"
      >
        <el-switch
          id="kvmLocalAutoDisable" 
          v-model="kvmData.autoCloseLocalDisplay"
          :disabled="!isOemKvmUser"
          @change="kvmAutoDisable"
        />
      </el-form-item>
      <!-- 虚拟键鼠持续连接 -->
      <el-form-item
        :label="$t('SERVICE_KVM_INVTED_KEYBOARD')"
        class="switch-value-item"
        size="default"
      >
        <el-switch
          id="persistentUSB"
          v-model="kvmData.persistentUSBConnectionEnabled"
          :disabled="!isOemKvmUser"
          @change="keyboardChange"
        />
      </el-form-item>
      <!-- 系统自动锁定 -->
      <el-form-item
        class="auto-lock-item"
        :label="$t('SERVICE_OS_AUTO_LOCK')"
        size="default"
      >
        <el-switch
          id="autoOSLockType"
          v-model="kvmData.autoOSLockEnabled"
          :disabled="!isOemKvmUser"
          @change="autoOSLockChange"
        />
        <el-form
          v-show="kvmData.autoOSLockEnabled"
          label-width="auto"
          label-position="left"
          class="auto-lock"
          :disabled="isSystemLock || !isOemKvmUser"
        >
          <!-- 系统自动锁定方式 -->
          <el-form-item :label="$t('SERVICE_LOCK_MODE')" class="switch-value-item" size="default">
            <el-radio-group v-model="kvmData.autoOSLockType" @change="sessionAutoOSTypeChange">
              <el-radio
                v-for="item in autoOSLockTypeList"
                :key="item.id"
                v-addId.radio="item.id"
                :label="item.id"
              >
                {{ item.label }}
              </el-radio>
            </el-radio-group>
          </el-form-item>
          <!-- 自定义快捷键 -->
          <el-form-item
            v-if="customShow"
            :label="$t('SERVICE_SHORTCUT_KEY')"
            prop="autoOSLockKey"
            class="auto-os-lock-key"
            :error="autoLockMsg"
          >
            <el-tooltip :content="$t('SERVICE_SHORTCUT_KEY_TIP')" placement="top" trigger-keys>
              <div class="tooltip-box">
                <el-input
                  v-model="kvmData.autoOSLockKey[0]"
                  v-addId.input="'lockKeyId1'"
                  class="lock-key"
                  readonly
                  @keydown.stop="setDefineKey($event, 0)"
                ></el-input>
                <span>+</span>
                <el-input
                  v-model="kvmData.autoOSLockKey[1]"
                  v-addId.input="'lockKeyId2'"
                  class="lock-key"
                  readonly
                  @keydown.stop="setDefineKey($event, 1)"
                ></el-input>
                <span>+</span>
                <el-input
                  v-model="kvmData.autoOSLockKey[2]"
                  v-addId.input="'lockKeyId3'"
                  class="lock-key"
                  readonly
                  @keydown.stop="setDefineKey($event, 2)"
                ></el-input>
                <span>+</span>
                <el-input
                  v-model="kvmData.autoOSLockKey[3]"
                  v-addId.input="'lockKeyId4'"
                  class="lock-key"
                  readonly
                  @keydown.stop="setDefineKey($event, 3)"
                ></el-input>
              </div>
            </el-tooltip>
            <el-button
              v-if="isOemKvmUser && !isSystemLock"
              id="clearKeyId"
              type="text"
              @click="clearNumberOfActiveSessions"
            >
              {{ $t('COMMON_CLEAR') }}
            </el-button>
          </el-form-item>
        </el-form>
      </el-form-item>
      <!-- 最大会话数 -->
      <el-form-item :label="$t('SERVICE_VNC_MAX_SESSION')" class="switch-value-item" size="default">
        <span id="maxSession">{{ kvmData.maximumNumberOfSessions }}</span>
      </el-form-item>
      <!-- 活跃会话数 -->
      <el-form-item :label="$t('SERVICE_ACTIVE_SESSIONS')" class="switch-value-item" size="default">
        <span id="kvmActtive">{{ kvmData.numberOfActiveSessions }}</span>
        <el-button
          id="checkKvmSession"
          :disabled="kvmData.numberOfActiveSessions === 0 || !isConfigureUser"
          type="text"
          @click="jumpToOnline"
        >
          {{ $t('ALARM_DETAILS') }}
        </el-button>
      </el-form-item>
      <!-- kvm保存 -->
      <el-form-item label=" ">
        <el-button
          v-if="isOemSecurityMgmtUser || isOemKvmUser || isBaseConfig"
          id="kvmButton"
          :disabled="!saveBtnState"
          type="primary"
          @click="submitBtn"
        >
          {{ $t('COMMON_SAVE') }}
        </el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<style lang="scss" scoped>
.kvm-container {
  background-color: var(--o-bg-color-base);
  border-radius: 4px;
  padding: 24px;
  height: auto !important;
  margin-right: 24px;

  :deep(.el-form-item) {
    &:nth-last-child(1) {
      margin: 0;
    }

    &.el-form-item {
      margin-bottom: var(--o-form-item-gap);

      &:nth-last-child(1) {
        margin-bottom: 0;
      }
    }

    .el-input {
      max-width: 320px;
    }

    .el-button--text {
      min-width: auto;
      margin: 0 8px;
      font-weight: 600;
    }
  }

  :deep(.switch-value-item) {
    height: 16px;
    .el-form-item__label {
      padding-top: 0;
      padding-bottom: 0;
    }

    .el-radio {
      height: auto;
    }
  }

  :deep(.special-item) {
    .el-form-item__label {
      padding-top: 0;
      padding-bottom: 0;
    }

    .el-radio {
      height: auto;
    }
  }

  :deep(.auto-os-lock-key) {
    .el-form-item__label {
      padding-top: 8px;
      padding-bottom: 8px;
    }
  }

  .tooltip-box {
    display: inline-block;
  }

  .auto-lock-item {
    > :deep(.el-form-item__label-wrap .el-form-item__label) {
      padding-top: 0;
      padding-bottom: 0;
    }
    :deep(.el-form-item__content) {
      display: inline-block;
    }
  }

  .auto-lock {
    background-color: var(--o-bg-color-light);
    padding: 24px;
    margin-top: 8px;
    border-radius: 2px;
  }

  .lock-key {
    width: 82px;
  }
}
</style>
